/*  tBookShelf: TextPlugin
    (C) 2007  TvN (Volodymyr Tarasenko), e-mail: tvntsr@yahoo.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef LUA_PARSER_TEXT_PLUGIN_HPP
#define LUA_PARSER_TEXT_PLUGIN_HPP

#include <list>
#include <string>
#include <stdexcept>

extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//:FIXME: ADD ERROR HANDLING!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


// :TODO:
// 0! hyphenation
// 1. locale
// 2. wide to char and char to wide conversion
// 3. iconv support as additional class

#include "PageManager.hpp"
#include "Utils/TextStyle.hpp"
#include "Utils/HyphenationManager.hpp"

extern void wcharToChar(char** dest, const wchar_t* data);
extern void charToWchar(wchar_t** dest, const char* data);

class ConfigParser
{
public:
    ConfigParser(const std::string&  main_cfg, 
                 const char*         file_name,
                 HyphenationManager* hman);
    ~ConfigParser() throw(); 

    void   addConfig(const std::string& cfg);

    void   recursiveConfig(const char* file_name); // Should it be public? 

    int    parseLine(const std::string& line, TextStyle& style);
    size_t transformLine(std::string& line);

    void   saveTextStyle(const TextStyle& style);

    void   getRegisteredStyles(std::list<std::string>&);
    void   getRegisteredProfiles(std::list<std::string>&);
    void   setProfile(const std::string& style);

    std::string getStringVariable(const char* var_name);

    // Created for simplicity, could be done via template lately
    int getIntegerVariable(const char* var_name);
    // The same as previous but could call lua function instread 
    // of reading value as variable
    int getIntegerData(const char* var_name);

    void setIntegerVariable(const char* var_name, const int& value);

    inline int getFontSize()
    {
        return  getIntegerVariable("fontSize");
    }
    inline int getInterWordSpace()
    {
        return  getIntegerVariable("interwordSpace");
    }
    inline int getInterLineSpace()
    {
        return  getIntegerVariable("interlineSpace");
    }
    inline int getBrightness()
    {
        return  getIntegerVariable("brightness");
    }
    inline int getContrast()
    {
        return  getIntegerVariable("contrast");
    }
    inline int getPageWidth(const PageOrientation& orient)
    {
        setIntegerVariable("PageOrientation", orient == Portrait ? 0: 1);

        return getIntegerData("PageWidth");
    }
    inline int getPageHeight(const PageOrientation& orient)
    {
        setIntegerVariable("PageOrientation", orient == Portrait ? 0: 1);

        return getIntegerData("PageHeight");
    }
    inline int getPageCacheSize()
    {
        return  getIntegerVariable("PageCacheSize");
    }
    inline int getPreRenderSize()
    {
        return  getIntegerVariable("PreRender");
    }
    inline std::string getDocType()
    {
        return getStringVariable("DocType");
    }

protected:
    inline void luaError()
    {
        const char* error = lua_tostring(L, -1);
        lua_pop(L, 1);

        throw std::runtime_error(error);
    }

    void standFunction(const char* oname, const char* name);
    std::string getStructName(const char* st);

    void doSaveText(const TextStyle& style);
    void createText(const TextStyle& style);
    void initTextStyle(TextStyle& style);

    bool getLuaValue(unsigned int& data, const char* name);
    bool getLuaValue(int& data, const char* name);
    bool getLuaValue(std::string& data, const char* name);

    void doLuaCall(int nargs, int nresults, int errfunc = 0);

private:
    std::string curr_profile;
    std::string name_style;
    lua_State*  L;

    HyphenationManager* mHyphenationManager;
};

#endif //LUA_PARSER_TEXT_PLUGIN_HPP
